package com.youlu.campus.service.data.impl;

import com.alibaba.fastjson.JSON;
import com.mongodb.client.result.UpdateResult;
import com.youlu.campus.base.exception.BusinessException;
import com.youlu.campus.wechat.service.impl.MerchantComplaintService;
import com.youlu.campus.entity.UniversityInfo;
import com.youlu.campus.entity.UserParticipateActivityInfo;
import com.youlu.campus.entity.VO.req.DataSimplingTaskQueryVO;
import com.youlu.campus.entity.data.DataSimplingTask;
import com.youlu.campus.entity.data.DataSimplingTaskDetail;
import com.youlu.campus.service.data.DataSimplingTaskDetailService;
import com.youlu.campus.service.data.DataSimplingTaskService;
import com.youlu.campus.service.visitor.UserBlackListService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.support.PageableExecutionUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.regex.Pattern;


@Slf4j
@Service
public class DataSimplingTaskServiceImpl implements DataSimplingTaskService {
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private UserBlackListService blackListService;
    @Autowired
    private MerchantComplaintService merchantComplaintService;
    @Autowired
    private DataSimplingTaskDetailService dataSimplingTaskDetailService;

    @Async
    @Override
    public boolean tempRun(DataSimplingTask req) {
        log.info(":>>> 开始运行标记任务:{}", "");
        DataSimplingTask taskUpdate = new DataSimplingTask();
        taskUpdate.setId(req.getId());
        taskUpdate.setStatus("running");
        this.update(taskUpdate);
        Query query = new Query();
        Date date = new Date();
        List<UniversityInfo> universityInfos = mongoTemplate.find(query, UniversityInfo.class);
        if (Objects.isNull(universityInfos) || CollectionUtils.isEmpty(universityInfos)) {
            log.error(":>>> 大学列表为空:");
            return false;
        }
        universityInfos = this.filterUniversity(universityInfos);
        Integer s = req.getNum() / universityInfos.size() + 1;
        log.info(":>>> 过滤学校后数量:{},过滤之前:{},每个学校抽样:{}", universityInfos.size(), universityInfos.size(), s);
        Query queryUser = new Query();
        for (UniversityInfo u : universityInfos) {
            queryUser.addCriteria(Criteria.where("universityId").is(u.getId()));
            queryUser.addCriteria(Criteria.where("simpled").ne(Boolean.TRUE));
            Sort sort = Sort.by(Sort.Direction.DESC, "createdTime");
            queryUser.with(sort);
            queryUser.limit(s * 10);
            List<UserParticipateActivityInfo> ups = mongoTemplate.find(queryUser, UserParticipateActivityInfo.class);
            if (Objects.isNull(ups) || CollectionUtils.isEmpty(ups)) {
                log.info(":>>> 用户参与信息为空:{}", JSON.toJSON(queryUser));
                continue;
            }
            Integer uTotal = 0;
            for (UserParticipateActivityInfo up : ups) {
                this.updateUserParticipateActivityInfo(up, date);
                if (uTotal.compareTo(s) == 1) {
                    break;
                }
                if (StringUtils.isBlank(up.getMobile())) {
                    log.error(":>>> 参与人名单:{},手机号为空", up.getId());
                    continue;
                }
                Boolean existBlackList = blackListService.existsByMobile(up.getMobile());
                Boolean existComplaint = merchantComplaintService.existWithMobile(up.getMobile());
                if (Boolean.TRUE.equals(existBlackList) || Boolean.TRUE.equals(existComplaint)) {
                    continue;
                } else {
                    uTotal++;
                    // 存储详情
                    DataSimplingTaskDetail dataSimplingTaskDetail = new DataSimplingTaskDetail();
                    dataSimplingTaskDetail.setTaskId(req.getId());
                    dataSimplingTaskDetail.setMobile(up.getMobile());
                    dataSimplingTaskDetail.setUniversityId(up.getUniversityId());
                    dataSimplingTaskDetail.setUniversityName(up.getUniversityName());
                    dataSimplingTaskDetail.setCreatedTime(date);
                    dataSimplingTaskDetailService.create(dataSimplingTaskDetail);
                }
            }

        }
        return true;
    }

    @Override
    public DataSimplingTask create(DataSimplingTask req) {
        req.setId(null);
        Date date = new Date();
        req.setCreatedTime(date);
//        req.setName("简单抽样" + date.getTime());
        req = mongoTemplate.insert(req);
        if (StringUtils.isNotBlank(req.getId())) {
            return req;
        }
        return null;
    }

    @Override
    public boolean update(DataSimplingTask req) {
        Query query = new Query();
        query.addCriteria(Criteria.where("id").is(req.getId()));
        Update update = new Update();
        boolean toUpdate = false;
        if (StringUtils.isNotBlank(req.getFileUrl())) {
            update.set("fileUrl", req.getFileUrl());
            toUpdate = true;
        }
        if (StringUtils.isNotBlank(req.getName())) {
            update.set("name", req.getName());
            toUpdate = true;
        }
        if (Objects.nonNull(req.getNum())) {
            update.set("num", req.getNum());
            toUpdate = true;
        }
        if (Objects.nonNull(req.getStartTime())) {
            update.set("startTime", req.getStartTime());
            toUpdate = true;
        }
        if (Objects.nonNull(req.getEndTime())) {
            update.set("endTime", req.getEndTime());
            toUpdate = true;
        }
        if (StringUtils.isNotBlank(req.getDesc())) {
            update.set("desc", req.getDesc());
            toUpdate = true;
        }
        if (StringUtils.isNotBlank(req.getStatus())) {
            update.set("status", req.getStatus());
            toUpdate = true;
        }
        if (toUpdate) {
            UpdateResult updateResult = mongoTemplate.updateFirst(query, update, DataSimplingTask.class);
            return updateResult.getModifiedCount() > 0 ? true : false;
        }
        return false;
    }

    @Override
    public Page<DataSimplingTask> list(DataSimplingTaskQueryVO req) {
        log.info(":>>> 开始抽样任务列表:{}", JSON.toJSONString(req));
        Query query = new Query();
        if (StringUtils.isNotBlank(req.getStatus())) {
            query.addCriteria(Criteria.where("status").is(req.getStatus()));
        }
        if (StringUtils.isNotBlank(req.getName())) {
            if (StringUtils.isNotBlank(req.getName())) {
                Pattern pattern = Pattern.compile("^.*" + req.getName() + ".*$", Pattern.CASE_INSENSITIVE);
                query.addCriteria(Criteria.where("name").regex(pattern));
            }
        }
        query.addCriteria(Criteria.where("deleted").ne(true));
        long count = mongoTemplate.count(query, DataSimplingTask.class);
        PageRequest pageRequest = PageRequest.of(req.getPage() - 1, req.getPageSize());
        Sort sort = Sort.by(Sort.Direction.DESC, "createdTime");
        query.with(sort);
        List<DataSimplingTask> infos = mongoTemplate.find(query.with(pageRequest), DataSimplingTask.class);
        return PageableExecutionUtils.getPage(infos, pageRequest, () -> count);
    }

    @Override
    public DataSimplingTask findOne(String id) {
        Query query = new Query();
        query.addCriteria(Criteria.where("id").is(id));
        return mongoTemplate.findOne(query, DataSimplingTask.class);
    }

    @Override
    public boolean start(String id) {
        DataSimplingTask task = this.findOne(id);
        if (!"todo".equals(task.getStatus())) {
            log.error(":>>> 任务状态错误:{}", task.getId());
            throw new BusinessException("任务状态错误");
        }
        this.tempRun(task);
        DataSimplingTask taskUpdate = new DataSimplingTask();
        taskUpdate.setId(id);
        taskUpdate.setStatus("done");
        this.update(taskUpdate);
        return false;
    }

    private List<UniversityInfo> filterUniversity(List<UniversityInfo> datas) {
        List<UniversityInfo> res = new ArrayList<>();
        for (UniversityInfo u : datas) {
            if (!StringUtils.isNotBlank(u.getName())) {
                continue;
            }
            if (u.getName().contains("中学") || u.getName().contains("小学")
                    || u.getName().contains("幼儿园") || u.getName().contains("高中") ||
                    u.getName().contains("学校") || u.getName().contains("一中") || u.getName().contains("二中")
                    || u.getName().contains("实验") || u.getName().contains("高中") || u.getName().contains("三中") || u.getName().contains("学校") ||
                    u.getName().contains("四中") || u.getName().contains("五中") || u.getName().contains("六中") || u.getName().contains("七中")
                    || u.getName().contains("八中") || u.getName().contains("九中") || u.getName().contains("十中") || u.getName().contains("十一中") || u.getName().contains("十二中")) {
                continue;
            } else {
                res.add(u);
            }
        }
        return res;

    }

    private void updateUserParticipateActivityInfo(UserParticipateActivityInfo up, Date date) {
        Query queryUp = new Query();
        queryUp.addCriteria(Criteria.where("id").is(up.getId()));
        Update updateUp = new Update();
        updateUp.set("simpled", Boolean.TRUE);
        updateUp.set("updatedTime", date);
        mongoTemplate.updateFirst(queryUp, updateUp, UserParticipateActivityInfo.class);
    }

}
